package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.mqtt.constant.MqttMsgConstants;
import com.csun.cmny.mqtt.entity.MsgButtonBind;
import com.csun.cmny.mqtt.entity.MsgHumidistatTimer;
import com.csun.cmny.mqtt.entity.MsgLifeBodySensorTimer;
import com.csun.cmny.provider.dao.DmcCsunGatewayBindMapper;
import com.csun.cmny.provider.dao.DmcCsunGatewayCmdHiMapper;
import com.csun.cmny.provider.dao.DmcCsunGatewayCmdMapper;
import com.csun.cmny.provider.device.csun.gateway.GatewayMessageSender;
import com.csun.cmny.provider.exceptions.DmcBizException;
import com.csun.cmny.provider.model.domain.*;
import com.csun.cmny.provider.model.dto.gateway.GatewayBindDto;
import com.csun.cmny.provider.model.enums.device.DmcDeviceTypeEnum;
import com.csun.cmny.provider.model.vo.GatewayReqVo;
import com.csun.cmny.provider.model.vo.device.DmcDeviceVo;
import com.csun.cmny.provider.model.vo.gateway.GatewayBindVo;
import com.csun.cmny.provider.resolver.CmnyMessageSource;
import com.csun.cmny.provider.service.*;
import com.csun.cmny.provider.utils.DateUtil;
import com.csun.cmny.util.PublicUtil;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-12-31 15:49
 * @Description:
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DmcCsunGatewayBindServiceImpl extends BaseService<DmcCsunGatewayBind>
        implements DmcCsunGatewayBindService {

    @Resource
    private CmnyMessageSource cmnyMessageSource;
    @Resource
    private DmcCsunGatewayBindMapper dmcCsunGatewayBindMapper;
    @Resource
    private DmcDeviceService dmcDeviceService;
    @Resource
    private GatewayMessageSender gatewayMessageSender;
    @Resource
    private DmcCsunGatewayConfigHumidistatService dmcCsunGatewayConfigHumidistatService;
    @Resource
    private DmcCsunGatewayCmdMapper dmcCsunGatewayCmdMapper;
    @Resource
    private DmcCsunGatewayCmdHiMapper dmcCsunGatewayCmdHiMapper;
    @Resource
    private DmcCsunHumidistatConfigService dmcCsunHumidistatConfigService;
    @Resource
    private DmcCsunBodySensorConfigService dmcCsunBodySensorConfigService;
    @Resource
    private DmcCsunGatewayConfigBodySensorService dmcCsunGatewayConfigBodySensorService;
    @Resource
    private DmcCsunHumidistatDataService dmcCsunHumidistatDataService;
    @Resource
    private DmcCsunHumidistatDataHiService dmcCsunHumidistatDataHiService;

    /**
     * query gateway bind device sensor list
     *
     * @param gatewayBindDto the gateway bind dto
     *
     * @return the gateway bind vo list.
     */
    @Override
    public List<GatewayBindVo> queryGatewayBindList(GatewayBindDto gatewayBindDto) {

        return dmcCsunGatewayBindMapper.queryGatewayBindList(gatewayBindDto);
    }

    /**
     * gateway bind device sensor  list
     *
     * @param gatewayBindDto the gatewaty bind dto
     *
     * @return the int
     */
    @Override
    public Integer gatewayBind(GatewayBindDto gatewayBindDto) {

        // 网关id不能为空
        Preconditions.checkArgument(PublicUtil.isNotEmpty(gatewayBindDto.getGatewayId()),
                cmnyMessageSource.getMessage("gateway.id.null", null));

        // 传感器id不能为空
//        Preconditions.checkArgument(PublicUtil.isNotEmpty(gatewayBindDto.getDeviceIdList()),
//                cmnyMessageSource.getMessage("gateway.device.id.null", null));
        /**
         * @date    2020-01-02
         * @author  chisj
         * @desc    如果待绑定的列表为空,则清空所有的绑定
         */

        // 根据网关Id查询网关编号
        DmcDevice gateway = dmcDeviceService.selectByKey(gatewayBindDto.getGatewayId());
        if (gateway == null) {
            // 网关不存在
            throw new DmcBizException(ErrorCodeEnum.DMC100614003);
        }
        if (gateway.getDeviceType().compareTo(DmcDeviceTypeEnum.CSUN_GATEWAY.getIndex()) != 0) {
            // 该设备不是网关
            throw new DmcBizException(ErrorCodeEnum.DMC100614004);
        }

        // 根据设备Id查询设备编号
        List<String> deviceNoList = Lists.newArrayList();
        List<DmcDeviceVo> dmcDeviceList = Lists.newArrayList();
        if (PublicUtil.isNotEmpty(gatewayBindDto.getDeviceIdList())) {
            dmcDeviceList = dmcDeviceService.queryDeviceListByIdList(gatewayBindDto.getDeviceIdList());
            for (DmcDeviceVo d : dmcDeviceList) {
                deviceNoList.add(d.getDeviceNo());
            }
        }

        /**
         * 清除温湿度计的数据
         */
        // 1.查找解绑的温湿度计Id
        List<Long> notBindIds = dmcCsunGatewayBindMapper
                .queryGatewayNotBindHumidistatIdList(gatewayBindDto);

        // 根据网关Id清空绑定
        DmcCsunGatewayBind bind = new DmcCsunGatewayBind();
        bind.setGatewayId(gatewayBindDto.getGatewayId());
        bind.setBindType(gatewayBindDto.getBindType());
        dmcCsunGatewayBindMapper.delete(bind);

        List<DmcCsunGatewayBind> bindList = Lists.newArrayList();
        // 绑定最新设备Id
        for (Long deviceId : gatewayBindDto.getDeviceIdList()) {
            DmcCsunGatewayBind b = new DmcCsunGatewayBind();
            b.setGatewayId(gatewayBindDto.getGatewayId());
            b.setBindType(gatewayBindDto.getBindType());
            b.setDeviceId(deviceId);

            bindList.add(b);
        }
        Integer result = batchSave(bindList);

        // 下发绑定消息
        /*************** 绑定温湿度计 ***************/
        if (DmcDeviceTypeEnum.HUMIDISTAT.getIndex().equals(gatewayBindDto.getBindType())) {

            // 2.根据温湿度计Id清除数据
            if (PublicUtil.isNotEmpty(notBindIds)) {
                // 删除温湿度计的数据
                dmcCsunHumidistatDataService.deleteByDeviceIds(notBindIds);
                // 删除温湿度计历史数据
                dmcCsunHumidistatDataHiService.deleteByDeviceIds(notBindIds);
            }

            saveGatewayConfigHumidistat(gateway.getId(), gateway.getDeviceNo(), dmcDeviceList);

            gatewayMessageSender.bindHumidistat(gateway.getId(), gateway.getDeviceNo(), deviceNoList);
        }

        /*************** 绑定新人感 ***************/
        if (DmcDeviceTypeEnum.NEWBODY.getIndex().equals(gatewayBindDto.getBindType())) {

            List<String> newList = Lists.newArrayList();

            saveGatewayConfigBodySensor(gateway.getId(), gateway.getDeviceNo(), dmcDeviceList);

            /**
             * 下发最后一个数字为偶数的设备编号
             */
            for (String d : deviceNoList) {
//                String tmp = d.substring(d.length() - 1, d.length());
//                if (tmp.equals("0")
//                        || tmp.equals("2")
//                        || tmp.equals("4")
//                        || tmp.equals("6")
//                        || tmp.equals("8")) {
//                    newList.add(d);
//                }

                newList.add(d);
            }


            gatewayMessageSender.bindBodySensor(gateway.getId(), gateway.getDeviceNo(), newList, "1");
        }


        /*************** 绑定温湿度计 ***************/
        if (DmcDeviceTypeEnum.CSUN_BUTTON.getIndex().equals(gatewayBindDto.getBindType())) {

            saveGatewayConfigButton(gateway.getId(), gateway.getDeviceNo(), dmcDeviceList);

            gatewayMessageSender.bindButton(gateway.getId(), gateway.getDeviceNo(), deviceNoList);
        }

        /*************** 绑定老人感 ***************/
        if (DmcDeviceTypeEnum.CSUN_BODY_SENSOR.getIndex().equals(gatewayBindDto.getBindType())) {

            List<String> newList = Lists.newArrayList();

            saveGatewayConfigBodySensor(gateway.getId(), gateway.getDeviceNo(), dmcDeviceList);

            /**
             * 下发最后一个数字为偶数的设备编号
             */
            for (String d : deviceNoList) {
                String tmp = d.substring(d.length() - 1, d.length());
                if (tmp.equals("0")
                        || tmp.equals("2")
                        || tmp.equals("4")
                        || tmp.equals("6")
                        || tmp.equals("8")) {
                    newList.add(d);
                }

            }


            gatewayMessageSender.bindBodySensor(gateway.getId(), gateway.getDeviceNo(), newList, "0");
        }



        return result;
    }

    private void saveGatewayConfigButton(Long gatewayId, String gatewayNo, List<DmcDeviceVo> dmcDeviceList) {

    }

    private void saveGatewayConfigBodySensor(Long gatewayId, String gatewayNo, List<DmcDeviceVo> dmcDeviceList) {
        // 删除所有的配置
        DmcCsunGatewayConfigBodySensor dmcCsunGatewayConfigBodySensor = new DmcCsunGatewayConfigBodySensor();
        dmcCsunGatewayConfigBodySensor.setGatewayId(gatewayId);
        dmcCsunGatewayConfigBodySensorService.delete(dmcCsunGatewayConfigBodySensor);

        // 删除所有待下发的指令
        DmcCsunGatewayCmd dmcCsunGatewayCmd = new DmcCsunGatewayCmd();
        dmcCsunGatewayCmd.setDeviceId(gatewayId);
        dmcCsunGatewayCmd.setMsgType(MqttMsgConstants.GATEWAY_BODY_SENSOR_SET_TIME_MSG);
        dmcCsunGatewayCmdMapper.delete(dmcCsunGatewayCmd);

        // 删除所有未下发成功的指令
        DmcCsunGatewayCmdHi dmcCsunGatewayCmdHi = new DmcCsunGatewayCmdHi();
        dmcCsunGatewayCmdHi.setDeviceId(gatewayId);
        dmcCsunGatewayCmdHi.setIsSend(0);
        dmcCsunGatewayCmdHi.setMsgType(MqttMsgConstants.GATEWAY_BODY_SENSOR_SET_TIME_MSG);
        dmcCsunGatewayCmdHiMapper.delete(dmcCsunGatewayCmdHi);

        // 配置
        List<DmcCsunGatewayConfigBodySensor> dmcCsunGatewayConfigBodySensorList = Lists.newArrayList();
        for (DmcDeviceVo dv : dmcDeviceList) {
            // 获取人感配置
            DmcCsunBodySensorConfig dmcCsunBodySensorConfig = dmcCsunBodySensorConfigService
                    .queryConfigByDeviceId(dv.getId());
            if (PublicUtil.isEmpty(dmcCsunBodySensorConfig)) {
                continue;
            }

            // 存储配置
            DmcCsunGatewayConfigBodySensor record = new DmcCsunGatewayConfigBodySensor();
            record.setGatewayId(gatewayId);
            record.setDeviceId(dv.getId());
            record.setIsSend(0);
            record.setToiletAttentionTime(dmcCsunBodySensorConfig.getToiletAttentionTime());
            record.setToiletWarningTime(dmcCsunBodySensorConfig.getToiletWarningTime());
            record.setToiletUnusualTime(dmcCsunBodySensorConfig.getToiletUnusualTime());
            dmcCsunGatewayConfigBodySensorList.add(record);

            // 待下发指令
            int qos = 0;
            MsgLifeBodySensorTimer msgLifeBodySensorTimer = new MsgLifeBodySensorTimer();

            msgLifeBodySensorTimer.setNetgateId(gatewayNo);
            msgLifeBodySensorTimer.setTimeOne(dmcCsunBodySensorConfig.getToiletAttentionTime().toString());
            msgLifeBodySensorTimer.setTimeTwo(dmcCsunBodySensorConfig.getToiletWarningTime().toString());
            msgLifeBodySensorTimer.setTimeThree(dmcCsunBodySensorConfig.getToiletUnusualTime().toString());
            msgLifeBodySensorTimer.setEventId(DateUtil.getDateStr(new Date()));
            msgLifeBodySensorTimer.setBodySensorId(dv.getDeviceNo());

            String msg = JSONObject.fromObject(msgLifeBodySensorTimer).toString();

            DmcCsunGatewayCmd cmd = new DmcCsunGatewayCmd();
            cmd.setDeviceId(gatewayId);
            cmd.setMsgType(msgLifeBodySensorTimer.getMsgType());
            cmd.setDeviceNo(gatewayNo);
            cmd.setContent(msg);
            cmd.setEventId(msgLifeBodySensorTimer.getEventId());
            cmd.setQos(qos);
            cmd.setSensorNo(dv.getDeviceNo());
            dmcCsunGatewayCmdMapper.saveOrUpdate(cmd);

            DmcCsunGatewayCmdHi cmdHi = new DmcCsunGatewayCmdHi();
            cmdHi.setContent(msg);
            cmdHi.setDeviceId(gatewayId);
            cmdHi.setDeviceNo(gatewayNo);
            cmdHi.setMsgType(msgLifeBodySensorTimer.getMsgType());
            cmdHi.setQos(qos);
            cmdHi.setEventId(msgLifeBodySensorTimer.getEventId());
            cmdHi.setSensorNo(dv.getDeviceNo());
            dmcCsunGatewayCmdHiMapper.insertSelective(cmdHi);

            // csunGatewayMessageGateway.sendToMqtt(gbv.getDeviceNo(), qos, msg);
        }

        if (PublicUtil.isNotEmpty(dmcCsunGatewayConfigBodySensorList)) {
            dmcCsunGatewayConfigBodySensorService.batchSave(dmcCsunGatewayConfigBodySensorList);
        }

        // 下发配置 -- 留着心跳的时候下发
    }

    /**
     * 查询传感器绑定的网关列表
     *
     * @param gatewayBindDto
     *
     * @return
     */
    @Override
    public List<GatewayBindVo> queryGatewayList(GatewayBindDto gatewayBindDto) {

        if (PublicUtil.isEmpty(gatewayBindDto.getDeviceIdList())) {
            return null;
        }

        return dmcCsunGatewayBindMapper.queryGatewayList(gatewayBindDto);
    }

    @Override
    public List<GatewayBindVo> listBindDevice(GatewayBindDto dto) {

        return dmcCsunGatewayBindMapper.listBindDevice(dto);
    }

    /**
     * 保存网关-温湿度计配置
     *
     * @param gatewayId
     * @param dmcDeviceList
     */
    public void saveGatewayConfigHumidistat(Long gatewayId, String gatewayNo, List<DmcDeviceVo> dmcDeviceList) {

        // 删除所有的配置
        DmcCsunGatewayConfigHumidistat dmcCsunGatewayConfigHumidistat = new DmcCsunGatewayConfigHumidistat();
        dmcCsunGatewayConfigHumidistat.setGatewayId(gatewayId);
        dmcCsunGatewayConfigHumidistatService.delete(dmcCsunGatewayConfigHumidistat);

        // 删除所有待下发的指令
        DmcCsunGatewayCmd dmcCsunGatewayCmd = new DmcCsunGatewayCmd();
        dmcCsunGatewayCmd.setDeviceId(gatewayId);
        dmcCsunGatewayCmd.setMsgType(MqttMsgConstants.GATEWAY_HUMIDISTAT_SET_TIME_MSG);
        dmcCsunGatewayCmdMapper.delete(dmcCsunGatewayCmd);

        // 删除所有未下发成功的指令
        DmcCsunGatewayCmdHi dmcCsunGatewayCmdHi = new DmcCsunGatewayCmdHi();
        dmcCsunGatewayCmdHi.setDeviceId(gatewayId);
        dmcCsunGatewayCmdHi.setMsgType(MqttMsgConstants.GATEWAY_HUMIDISTAT_SET_TIME_MSG);
        dmcCsunGatewayCmdHi.setIsSend(0);
        dmcCsunGatewayCmdHiMapper.delete(dmcCsunGatewayCmdHi);

        // 配置
        List<DmcCsunGatewayConfigHumidistat> dmcCsunGatewayConfigHumidistatList = Lists.newArrayList();
        for (DmcDeviceVo dv : dmcDeviceList) {
            // 获取温湿度配置
            DmcCsunHumidistatConfig dmcCsunHumidistatConfig = dmcCsunHumidistatConfigService
                    .queryConfigByDeviceId(dv.getId());
            if (PublicUtil.isEmpty(dmcCsunHumidistatConfig)) {
                continue;
            }

            // 存储配置
            DmcCsunGatewayConfigHumidistat record = new DmcCsunGatewayConfigHumidistat();
            record.setGatewayId(gatewayId);
            record.setDeviceId(dv.getId());
            record.setIsSend(0);
            record.setDuration(dmcCsunHumidistatConfig.getTemperatureMeasuringTimeInterval());
            dmcCsunGatewayConfigHumidistatList.add(record);

            // 待下发指令
            int qos = 0;
            MsgHumidistatTimer msgHumidistatTimer = new MsgHumidistatTimer();

            msgHumidistatTimer.setNetgateId(gatewayNo);
            msgHumidistatTimer.setDuration(dmcCsunHumidistatConfig.getTemperatureMeasuringTimeInterval().toString());
            msgHumidistatTimer.setEventId(DateUtil.getDateStr(new Date()));
            msgHumidistatTimer.setHumidistatId(dv.getDeviceNo());

            String msg = JSONObject.fromObject(msgHumidistatTimer).toString();

            DmcCsunGatewayCmd cmd = new DmcCsunGatewayCmd();
            cmd.setDeviceId(gatewayId);
            cmd.setMsgType(msgHumidistatTimer.getMsgType());
            cmd.setDeviceNo(gatewayNo);
            cmd.setContent(msg);
            cmd.setEventId(msgHumidistatTimer.getEventId());
            cmd.setQos(qos);
            cmd.setSensorNo(dv.getDeviceNo());
            dmcCsunGatewayCmdMapper.saveOrUpdate(cmd);

            DmcCsunGatewayCmdHi cmdHi = new DmcCsunGatewayCmdHi();
            cmdHi.setContent(msg);
            cmdHi.setDeviceId(gatewayId);
            cmdHi.setDeviceNo(gatewayNo);
            cmdHi.setMsgType(msgHumidistatTimer.getMsgType());
            cmdHi.setQos(qos);
            cmdHi.setEventId(msgHumidistatTimer.getEventId());
            cmdHi.setSensorNo(dv.getDeviceNo());
            dmcCsunGatewayCmdHiMapper.insertSelective(cmdHi);

                // csunGatewayMessageGateway.sendToMqtt(gbv.getDeviceNo(), qos, msg);
        }

        if (PublicUtil.isNotEmpty(dmcCsunGatewayConfigHumidistatList)) {
            dmcCsunGatewayConfigHumidistatService.batchSave(dmcCsunGatewayConfigHumidistatList);
        }

        // 下发配置 -- 留着心跳的时候下发
    }
}
